package fr.greta.centreFormation.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;

import fr.greta.centreFormation.bean.Administrateur;
import fr.greta.centreFormation.bean.Candidat;
import fr.greta.centreFormation.bean.Diplome;
import fr.greta.centreFormation.bean.Etat;
import fr.greta.centreFormation.bean.Promotion;

/**
 * CandidatHome est la classe regroupant les methodes d'acces a la base de donnees concernant les Candidats
 * 
 * @author dgidgib
 *
 */
public class CandidatHome {

	/**
	 * retourne tous les candidats
	 * 
	 * @return une Arraylist de candidats
	 */
	public static ArrayList<Candidat> selectAllCandidat() {

		ArrayList<Candidat> collectionDeCandidat = new ArrayList<Candidat>();
		String select = "SELECT * FROM personne p INNER JOIN candidat c ON p.id_personne = c.id_personne";

		try {
			Connection connection = Bdd.getConnection();
			PreparedStatement stmt = connection.prepareStatement(select);
			ResultSet resultat = stmt.executeQuery();

			while (resultat.next()) {

				int idEtat = resultat.getInt("id_etat");
				Etat etat = EtatHome.selectUnEtatByIdEtat(idEtat);
				Candidat candidat = new Candidat();
				candidat.setEtat(etat);
				candidat.setIdPersonne(resultat.getInt("id_personne"));
				candidat.setNom(resultat.getString("nom_personne"));
				candidat.setPrenom(resultat.getString("prenom_personne"));
				candidat.setMail(resultat.getString("mail_personne"));
				candidat.setNumTel1(resultat.getString("tel1_personne"));
				candidat.setNumtel2(resultat.getString("tel2_personne"));
				candidat.setDateNaissance(resultat
						.getDate("date_naissance_personne"));
				candidat.setAdresse(resultat.getString("adresse_personne"));
				candidat.setVille(resultat.getString("ville_personne"));
				candidat.setCodePostale(resultat.getInt("code_postal_personne"));
				candidat.setLogin(resultat.getString("login_personne"));
				candidat.setPassword(resultat
						.getString("mot_de_passe_personne"));

				candidat.setCompetence(resultat
						.getString("competence_info_candidat"));
				candidat.setMotivation(resultat
						.getString("motivation_candidat"));
				candidat.setCv(resultat.getString("cv_candidat"));
				candidat.setClef(resultat.getString("clef_mail_candidat"));

				ArrayList<Promotion> lesPromo = new ArrayList<Promotion>();
				lesPromo = PromotionHome
						.selectAllPromotionByIdPersonne(resultat
								.getInt("id_personne"));
				candidat.setCollectionDePromotions(lesPromo);

				collectionDeCandidat.add(candidat);

			}

			return collectionDeCandidat;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}

	/**
	 * retourne les candidats selon l'Etat de leur candidature
	 * 
	 * @param idEtat
	 *            l'id de l'Etat
	 * @return une Arraylist de candidats
	 */
	public static ArrayList<Candidat> selectAllCandidatByIdEtat(int idEtat) {

		ArrayList<Candidat> collectionDeCandidat = new ArrayList<Candidat>();
		String select = "SELECT * FROM personne p INNER JOIN candidat c ON p.id_personne = c.id_personne WHERE id_etat = ?";

		try {
			PreparedStatement stmt = Bdd.getConnection().prepareStatement(
					select);
			stmt.setInt(1, idEtat);
			ResultSet resultat = stmt.executeQuery();

			while (resultat.next()) {

				Etat etat = EtatHome.selectUnEtatByIdEtat(idEtat);
				Candidat candidat = new Candidat(etat);
				candidat.setIdPersonne(resultat.getInt("id_personne"));
				candidat.setNom(resultat.getString("nom_personne"));
				candidat.setPrenom(resultat.getString("prenom_personne"));
				candidat.setMail(resultat.getString("mail_personne"));
				candidat.setNumTel1(resultat.getString("tel1_personne"));
				candidat.setNumtel2(resultat.getString("tel2_personne"));
				candidat.setDateNaissance(resultat
						.getDate("date_naissance_personne"));
				candidat.setAdresse(resultat.getString("adresse_personne"));
				candidat.setVille(resultat.getString("ville_personne"));
				candidat.setCodePostale(resultat.getInt("code_postal_personne"));
				candidat.setLogin(resultat.getString("login_personne"));
				candidat.setPassword(resultat
						.getString("mot_de_passe_personne"));

				candidat.setCompetence(resultat
						.getString("competence_info_candidat"));
				candidat.setMotivation(resultat
						.getString("motivation_candidat"));
				candidat.setCv(resultat.getString("cv_candidat"));
				candidat.setClef(resultat.getString("clef_mail_candidat"));

				ArrayList<Promotion> lesPromo = new ArrayList<Promotion>();
				lesPromo = PromotionHome
						.selectAllPromotionByIdPersonne(resultat
								.getInt("id_personne"));
				candidat.setCollectionDePromotions(lesPromo);

				collectionDeCandidat.add(candidat);

			}

			return collectionDeCandidat;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}

	/**
	 * retourne les candidats par l'id de la promotion
	 * 
	 * @param idPromo
	 *            l'id de la promotion
	 * @return une arraylist de candidats
	 */
	public static ArrayList<Candidat> selectAllCandidatByIdPromotion(int idPromo) {

		ArrayList<Candidat> collectionDeCandidat = new ArrayList<Candidat>();
		String select = "SELECT * FROM personne p"
				+ "		INNER JOIN candidat c ON p.id_personne = c.id_personne"
				+ "		INNER JOIN candidat_promotion cp ON c.id_candidat = cp.id_candidat "
				+ "		INNER JOIN promotion pr ON pr.id_promotion = cp.id_promotion"
				+ "		WHERE pr.id_promotion = ?";

		try {
			PreparedStatement stmt = Bdd.getConnection().prepareStatement(
					select);
			stmt.setInt(1, idPromo);
			ResultSet resultat = stmt.executeQuery();

			while (resultat.next()) {

				int idEtat = resultat.getInt("id_etat");
				Etat etat = EtatHome.selectUnEtatByIdEtat(idEtat);
				Candidat candidat = new Candidat(etat);
				candidat.setIdPersonne(resultat.getInt("id_personne"));
				candidat.setNom(resultat.getString("nom_personne"));
				candidat.setPrenom(resultat.getString("prenom_personne"));
				candidat.setMail(resultat.getString("mail_personne"));
				candidat.setNumTel1(resultat.getString("tel1_personne"));
				candidat.setNumtel2(resultat.getString("tel2_personne"));
				candidat.setDateNaissance(resultat
						.getDate("date_naissance_personne"));
				candidat.setAdresse(resultat.getString("adresse_personne"));
				candidat.setVille(resultat.getString("ville_personne"));
				candidat.setCodePostale(resultat.getInt("code_postal_personne"));
				candidat.setLogin(resultat.getString("login_personne"));
				candidat.setPassword(resultat
						.getString("mot_de_passe_personne"));

				candidat.setCompetence(resultat
						.getString("competence_info_candidat"));
				candidat.setMotivation(resultat
						.getString("motivation_candidat"));
				candidat.setCv(resultat.getString("cv_candidat"));
				candidat.setClef(resultat.getString("clef_mail_candidat"));

				ArrayList<Promotion> lesPromo = new ArrayList<Promotion>();
				lesPromo = PromotionHome
						.selectAllPromotionByIdPersonne(resultat
								.getInt("id_personne"));
				candidat.setCollectionDePromotions(lesPromo);

				collectionDeCandidat.add(candidat);

			}

			return collectionDeCandidat;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}

	/**
	 * retourne un candidat par son Id Personne
	 * 
	 * @param idPersonne
	 *            l'Id de la personne
	 * @return le candidat
	 */
	public static Candidat selectUnCandidatByIdPersonne(int idPersonne) {

		Etat etat = new Etat();
		Candidat candidat = new Candidat(etat);

		String select = "SELECT * FROM personne p INNER JOIN candidat c ON p.id_personne = c.id_personne WHERE p.id_Personne = ?";

		try {
			PreparedStatement stmt = Bdd.getConnection().prepareStatement(
					select);
			stmt.setInt(1, idPersonne);
			ResultSet resultat = stmt.executeQuery();

			resultat.next();
			etat = EtatHome.selectUnEtatByIdEtat(resultat.getInt("id_etat"));
			candidat.setEtat(etat);

			candidat.setIdPersonne(resultat.getInt("id_personne"));
			candidat.setNom(resultat.getString("nom_personne"));
			candidat.setPrenom(resultat.getString("prenom_personne"));
			candidat.setMail(resultat.getString("mail_personne"));
			candidat.setNumTel1(resultat.getString("tel1_personne"));
			candidat.setNumtel2(resultat.getString("tel2_personne"));
			candidat.setDateNaissance(resultat
					.getDate("date_naissance_personne"));
			candidat.setAdresse(resultat.getString("adresse_personne"));
			candidat.setVille(resultat.getString("ville_personne"));
			candidat.setCodePostale(resultat.getInt("code_postal_personne"));
			candidat.setLogin(resultat.getString("login_personne"));
			candidat.setPassword(resultat.getString("mot_de_passe_personne"));

			candidat.setCompetence(resultat
					.getString("competence_info_candidat"));
			candidat.setMotivation(resultat.getString("motivation_candidat"));
			candidat.setCv(resultat.getString("cv_candidat"));
			candidat.setClef(resultat.getString("clef_mail_candidat"));

			ArrayList<Promotion> lesPromo = new ArrayList<Promotion>();
			lesPromo = PromotionHome.selectAllPromotionByIdPersonne(resultat
					.getInt("id_personne"));
			candidat.setCollectionDePromotions(lesPromo);

			return candidat;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return candidat;
		}

	}

	/**
	 * retourne l'Id du candidat par son Id Personne
	 * 
	 * @param idPersonne
	 *            l'Id de la personne
	 * @return l'Id du candidat
	 */
	public static int selectIdCandidatByIdPersonne(int idPersonne) {

		String select = "SELECT id_candidat FROM candidat c INNER JOIN personne p ON c.id_personne = p.id_personne WHERE c.id_personne = ?";

		try {
			PreparedStatement stmt = Bdd.getConnection().prepareStatement(
					select);
			stmt.setInt(1, idPersonne);
			ResultSet resultat = stmt.executeQuery();

			resultat.next();
			int idCandidat = resultat.getInt(1);

			return idCandidat;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}

	}

	/**
	 * insere un candidat dans la base de donnees
	 * 
	 * @param candidat
	 *            le candidat concerne
	 * @return l'id du candidat
	 */
	public static int insertUnCandidat(Candidat candidat) {

		int idPersonne = 0;
		String insertPersonne = "INSERT INTO personne "
				+ "(nom_personne, prenom_personne, mail_personne, "
				+ "tel1_personne, tel2_personne, date_naissance_personne, "
				+ "adresse_personne, ville_personne, code_postal_personne, "
				+ "login_personne, mot_de_passe_personne) "
				+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

		int idCandidat = 0;
		String insertCandidat = "INSERT INTO candidat "
				+ "(competence_info_candidat, motivation_candidat, cv_candidat, id_personne, id_etat, clef_mail_candidat)"
				+ "VALUES (?, ?, ?, ?, ?, ?)";

		try {
			// Insertion dans la table personne :
			// -------------------------------------
			PreparedStatement stmtPersonne = Bdd.getConnection()
					.prepareStatement(insertPersonne,
							Statement.RETURN_GENERATED_KEYS);
			stmtPersonne.setString(1, candidat.getNom());
			stmtPersonne.setString(2, candidat.getPrenom());
			stmtPersonne.setString(3, candidat.getMail());
			stmtPersonne.setString(4, candidat.getNumTel1());
			stmtPersonne.setString(5, candidat.getNumtel2());
			Date dateNaissance = candidat.getDateNaissance();
			java.sql.Date dateNaissanceSql = new java.sql.Date(
					dateNaissance.getTime());
			stmtPersonne.setDate(6, dateNaissanceSql);
			stmtPersonne.setString(7, candidat.getAdresse());
			stmtPersonne.setString(8, candidat.getVille());
			stmtPersonne.setInt(9, candidat.getCodePostale());
			stmtPersonne.setString(10, candidat.getLogin());
			stmtPersonne.setString(11, candidat.getPassword());
			stmtPersonne.executeUpdate();

			ResultSet resultatPersonne = stmtPersonne.getGeneratedKeys();
			resultatPersonne.next();
			idPersonne = resultatPersonne.getInt(1);

			// Insertion dans la table candidat :
			// -------------------------------------
			PreparedStatement stmtCandidat = Bdd.getConnection()
					.prepareStatement(insertCandidat,
							Statement.RETURN_GENERATED_KEYS);
			stmtCandidat.setString(1, candidat.getCompetence());
			stmtCandidat.setString(2, candidat.getMotivation());
			stmtCandidat.setString(3, candidat.getCv());
			stmtCandidat.setInt(4, idPersonne);
			stmtCandidat.setInt(5, 1); // <= insert idEtat 1
			stmtCandidat.setString(6, candidat.genererClef());
			stmtCandidat.executeUpdate();

			ResultSet resultatCandidat = stmtCandidat.getGeneratedKeys();
			resultatCandidat.next();
			idCandidat = resultatCandidat.getInt(1);

			return idCandidat;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

			return 0;
		}

	}

	/**
	 * met à jour les donnees d'un candidat
	 * 
	 * @param candidat
	 *            le candidat concerne retourne vrai si la mise à jour s'est
	 *            bien passee faux si la mise à jour n'a pas été effectuee 
	 */
	public static Boolean updateUnCandidat(Candidat candidat) {

		String updatePersonne = "UPDATE personne SET "
				+ "nom_personne = ?, prenom_personne = ?, mail_personne = ?, "
				+ "tel1_personne = ?, tel2_personne = ?, date_naissance_personne = ?, "
				+ "adresse_personne = ?, ville_personne = ?, code_postal_personne = ?, "
				+ "login_personne = ?, mot_de_passe_personne = ?"
				+ "WHERE id_personne = ?";

		String updateCandidat = "UPDATE candidat SET competence_info_candidat = ?, motivation_candidat = ?, cv_candidat = ?, id_etat = ? WHERE id_personne = ?";

		try {
			// Update dans la table personne :
			// ----------------------------------
			PreparedStatement stmtPersonne = Bdd.getConnection()
					.prepareStatement(updatePersonne);
			stmtPersonne.setString(1, candidat.getNom());
			stmtPersonne.setString(2, candidat.getPrenom());
			stmtPersonne.setString(3, candidat.getMail());
			stmtPersonne.setString(4, candidat.getNumTel1());
			stmtPersonne.setString(5, candidat.getNumtel2());
			Date dateNaissance = candidat.getDateNaissance();
			java.sql.Date dateNaissanceSql = new java.sql.Date(
					dateNaissance.getTime());
			stmtPersonne.setDate(6, dateNaissanceSql);
			stmtPersonne.setString(7, candidat.getAdresse());
			stmtPersonne.setString(8, candidat.getVille());
			stmtPersonne.setInt(9, candidat.getCodePostale());
			stmtPersonne.setString(10, candidat.getLogin());
			stmtPersonne.setString(11, candidat.getPassword());
			stmtPersonne.setInt(12, candidat.getIdPersonne());
			stmtPersonne.executeUpdate();

			// Update dans la table candidat :
			// -----------------------------------
			PreparedStatement stmtCandidat = Bdd.getConnection()
					.prepareStatement(updateCandidat);
			stmtCandidat.setString(1, candidat.getCompetence());
			stmtCandidat.setString(2, candidat.getMotivation());
			stmtCandidat.setString(3, candidat.getCv());
			stmtCandidat.setInt(4, candidat.getEtat().getIdEtat());
			stmtCandidat.setInt(5, candidat.getIdPersonne());
			stmtCandidat.executeUpdate();

			return true;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}

	}

	/**
	 * supprime un candidat de la base de donnees
	 * 
	 * @param candidat
	 *            le candidat sélectionne
	 * @return vrai si la suppression s'est bien déroulee faux dans le cas
	 *         contraire
	 */
	public static Boolean deleteUnCandidat(Candidat candidat) {

		String deleteCandidat = "DELETE FROM candidat WHERE id_personne = ?";
		String deletePersonne = "DELETE FROM personne WHERE id_personne = ?";

		try {
			PreparedStatement stmtCandidat = Bdd.getConnection()
					.prepareStatement(deleteCandidat);
			stmtCandidat.setInt(1, candidat.getIdPersonne());
			stmtCandidat.executeUpdate();

			PreparedStatement stmtPersonne = Bdd.getConnection()
					.prepareStatement(deletePersonne);
			stmtPersonne.setInt(1, candidat.getIdPersonne());
			stmtPersonne.executeUpdate();

			return true;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * verifie si le candidat existe dans la base de donnees
	 * 
	 * @param login
	 *            le login saisi dans le formulaire de connexion
	 * @param password
	 *            le mot de passe saisi dans le formulaire
	 * @return le candidat sélectionne
	 */
	public static Candidat selectUnCandidatByLoginPassword(String login,
			String password) {

		Candidat unCandidat = new Candidat();

		String select = "SELECT * FROM personne p INNER JOIN candidat c ON p.id_personne=c.id_personne INNER JOIN diplome_candidat dc ON dc.id_candidat=c.id_candidat WHERE p.login_personne=? AND p.mot_de_passe_personne=?";

		Connection connection;
		try {
			connection = Bdd.getConnection();
			PreparedStatement stmt = connection.prepareStatement(select);

			stmt.setString(1, login);
			stmt.setString(2, password);

			ResultSet result = stmt.executeQuery();

			result.next();

			unCandidat.setIdPersonne(result.getInt("id_personne"));
			unCandidat.setNom(result.getString("nom_personne"));
			unCandidat.setPrenom(result.getString("prenom_personne"));
			unCandidat.setMail(result.getString("mail_personne"));
			unCandidat.setNumTel1(result.getString("tel1_personne"));
			unCandidat.setNumtel2(result.getString("tel2_personne"));
			unCandidat.setDateNaissance(result
					.getDate("date_naissance_personne"));
			unCandidat.setAdresse(result.getString("adresse_personne"));
			unCandidat.setVille(result.getString("ville_personne"));
			unCandidat.setCodePostale(result.getInt("code_postal_personne"));
			unCandidat.setLogin(login);
			unCandidat.setPassword(password);
			Diplome diplome = new Diplome();
			diplome = DiplomeHome.selectUnDiplomeByIdDiplome(result
					.getInt("id_diplome"));
			unCandidat.setDiplome(diplome);
			unCandidat.setCompetence(result
					.getString("competence_info_candidat"));
			unCandidat.setMotivation(result.getString("motivation_candidat"));
			unCandidat.setCv(result.getString("cv_candidat"));
			Etat etat = new Etat();
			etat = EtatHome.selectUnEtatByIdCandidat(result
					.getInt("id_candidat"));
			unCandidat.setEtat(etat);

			ArrayList<Promotion> lesPromo = new ArrayList<Promotion>();
			lesPromo = PromotionHome.selectAllPromotionByIdPersonne(result
					.getInt("id_personne"));
			unCandidat.setCollectionDePromotions(lesPromo);

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

		return unCandidat;
	}

}
